package com.itic.appbase.framework.utils.configuration;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.itic.appbase.framework.utils.StringHelper;

public class ConfigurationFactory {

    private static Logger LOGGER = LoggerFactory.getLogger(ConfigurationFactory.class);

    private static String path = "";

    private static final String DEFAULT_CFG_FILE = "config.xml";

    private static XPathFactory xpathFactory = XPathFactory.newInstance();

    private static XPath xpath = xpathFactory.newXPath();

    private static Configuration _configurationInstance = null;

    private static XPathExpression RESOURCE_XPATH_EXPRESSION;

    static {
        try {
            RESOURCE_XPATH_EXPRESSION = xpath.compile("//properties/@resource");
        } catch (Exception ex) {
            LOGGER.error("Xpath error", ex);
        }
    }

    private ConfigurationFactory() {

    }

    public static synchronized Configuration getConfiguration() {
        if (_configurationInstance != null) {
            return _configurationInstance;
        }
        try {
            System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
                    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(false);
            //factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            DocumentBuilder builder = factory.newDocumentBuilder();

            InputStream is = ClassLoaderUtils.getStream(getPath() + "/" + DEFAULT_CFG_FILE);
            if (is == null) {
                LOGGER.warn("没有默认资源配置文件" + getPath() + "/" + DEFAULT_CFG_FILE);
                return null;
            }
            Document xmlDoc = builder.parse(is);
            if (xmlDoc == null) {
                return null;
            }
            NodeList resourceNodes = (NodeList) RESOURCE_XPATH_EXPRESSION.evaluate(xmlDoc, XPathConstants.NODESET);
            List<String> resourceNames = new ArrayList<String>();
            for (int i = 0, size = resourceNodes.getLength(); i < size; i++) {
            	Node item = resourceNodes.item(i);
            	String textContent = item.getNodeValue();
                resourceNames.add(StringHelper.trimToEmpty(textContent));
            }
            _configurationInstance = new MixedConfiguration(resourceNames.toArray(new String[] {}));
            return _configurationInstance;
        } catch (ParserConfigurationException | SAXException | XPathExpressionException | IOException ex) {
            LOGGER.error("Get Configuration Error", ex);
        }
        return null;
    }

    public static String getPath() {
        return path;
    }

    public static void setPath(String path) {
        ConfigurationFactory.path = path;
    }

}
